//<<<+++OPENSOURCE
//<<<+++OPENSOURCE_LICENSE
//<<<+++OPENSOURCE_MUST_BEGIN
#ifndef _FX_FONT_H_
#define _FX_FONT_H_

#ifndef _FXCRT_EXTENSION_
	#include "../../include/fxcrt/fx_ext.h"
#endif

#ifndef _FX_DIB_H_
#include "fx_dib.h"
#endif
//<<<+++OPENSOURCE_MUST_END
/**@brief FreeType root face class structure. A face object models a
  *typeface in a font file.
  */
typedef struct FT_FaceRec_* FXFT_Face;
typedef void* FXFT_Library;
class IFX_FontEncoding;
class CFX_PathData;
class CFX_SubstFont;
class CFX_FaceCache;
class IFX_FontMapper;
class CFX_FontMapper;
class IFX_SystemFontInfo;
class CFontFileFaceInfo;

/**
 * @name Basic font flags, same as flags used in PDF fonts
 */
/*@{*/
#define FXFONT_FIXED_PITCH		0x01
#define FXFONT_SERIF			0x02
#define FXFONT_SYMBOLIC			0x04
#define FXFONT_SCRIPT			0x08
#define FXFONT_ITALIC			0x40
#define FXFONT_BOLD				0x40000
/*@}*/

/** 
 * @name Additional font flags, same as flags used in PDF fonts
 */
/*@{*/
#define FXFONT_USEEXTERNATTR	0x80000
/*@}*/

/**
 * @name Font type IDs.
 */
/*@{*/

/** @brief CID font. */
#define FXFONT_CIDFONT			0x100000

/*@}*/

/**
 * @name Font charsets, same as defined in Win32 font charsets
 */
/*@{*/
#define FXFONT_ANSI_CHARSET		0
#define FXFONT_DEFAULT_CHARSET	1
#define FXFONT_SYMBOL_CHARSET	2
#define FXFONT_SHIFTJIS_CHARSET	128
#define FXFONT_HANGEUL_CHARSET	129
#define FXFONT_GB2312_CHARSET	134
#define FXFONT_CHINESEBIG5_CHARSET	136
#define FXFONT_THAI_CHARSET		222
#define FXFONT_EASTEUROPE_CHARSET	238
#define FXFONT_RUSSIAN_CHARSET	204
#define FXFONT_GREEK_CHARSET	161
#define FXFONT_TURKISH_CHARSET	162
#define FXFONT_HEBREW_CHARSET	177
#define FXFONT_ARABIC_CHARSET	178
#define FXFONT_BALTIC_CHARSET	186
//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
#define FXFONT_VIETNAMESE_CHARSET  163
//<<<+++OPENSOURCE_END
/*@}*/

/**
 * @name Font families and weights, same as defined in Win32
 */
/*@{*/
#define FXFONT_FF_FIXEDPITCH	1
#define FXFONT_FF_ROMAN			(1<<4)
#define FXFONT_FF_SCRIPT		(4<<4)
#define FXFONT_FW_NORMAL		400
#define FXFONT_FW_BOLD			700
/*@}*/

//#define FXFONT_GE_USECACHE_

class CFX_Font : public CFX_Object
{
public:
	CFX_Font();
	~CFX_Font();

	/** Load a font through font mapper 
     *
     * @param[in] face_name         PostScript name
     * @param[in] bTrueType			TrueType or Type1.
	 * @param[in] flags				PDF font flags (see PDF Reference section 5.7.1).
	 * @param[in] weight            original font weight. 0 for not specified.
     * @param[in] italic_angle      original font italic angle. 0 for not specified.
	 * @param[in] CharsetCP			code page for charset (see Win32 GetACP()).
	 * @param[in] bVertical         Whether vertical writing-mode
	 * @return None-zero means success, otherwise failure.
     */
	FX_BOOL					LoadSubst(const CFX_ByteString& face_name, FX_BOOL bTrueType, FX_DWORD flags,
								int weight, int italic_angle, int CharsetCP, FX_BOOL bVertical = FALSE);

	/** Load an embedded font */
	FX_BOOL					LoadEmbedded(FX_LPCBYTE data, FX_DWORD size);

	/** Load file based font. Caller can't release the file until the font is released. */
	FX_BOOL					LoadFile(IFX_FileRead* pFile);
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	FX_BOOL					LoadMemory(int fontid);

	FX_BOOL					GetGlyphBitmapBearing(unsigned long glyph_index,
								CFX_AffineMatrix* matrix, double font_size,
											int* bitmap_left, int* bitmap_top);
	

	/** Create a logic font, this font must be newly constructed. */
	FX_BOOL                 LoadClone(const CFX_Font* pFont);
	//<<<+++OPENSOURCE_END
	/** Get FreeType face. */
	FXFT_Face				GetFace() const { return m_Face; }
	
	/** Get substitition information from the font mapper */
	const CFX_SubstFont*	GetSubstFont() const { return m_pSubstFont; }

	/** Load glyph path data */
	CFX_PathData*			LoadGlyphPath(FX_DWORD glyph_index, int dest_width = 0);

	/** Get glyph width in 1/1000 of em size (PDF units) */
	int						GetGlyphWidth(FX_DWORD glyph_index);

	/** Get font ascent, in 1/1000 of em size (PDF units) */
	int						GetAscent() const;

	/** Get font descent, in 1/1000 of em size (PDF units) */
	int						GetDescent() const;

	/** Get bounding box, in 1/1000 of em size (PDF units)*/
	FX_BOOL                 GetGlyphBBox(FX_DWORD glyph_index, FX_RECT &bbox);

	/** whether it is italic font.*/
	FX_BOOL                 IsItalic();

	/** whether it is bold font.*/
	FX_BOOL                 IsBold();

	/** whether it is fixed width font.*/
	FX_BOOL                 IsFixedWidth();

	/** whether font is for vertical writing mode */
	FX_BOOL					IsVertical() const { return m_bVertical; }

	/** Get font's postscript name.*/
	CFX_WideString          GetPsName() const;
	
	/** Get font's family name.*/
	CFX_ByteString          GetFamilyName() const;

	/** Get font's face name.*/
	CFX_ByteString          GetFaceName() const;
	
	/** whether it is truetype font.*/
	FX_BOOL                 IsTTFont();
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	/** whether it is cff font.*/
	FX_BOOL					IsCFFFont();
	//<<<+++OPENSOURCE_END
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	/** whether it is cid font.*/
	FX_BOOL                 IsCIDFont();
	//<<<+++OPENSOURCE_END
	/**Get font's boundingbox, in 1/1000 of em size (PDF units)*/
	FX_BOOL                 GetBBox(FX_RECT &bbox);

	/**Get font's height, in 1/1000 of em size (PDF units)*/
	int                     GetHeight();
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	/**Get font's capheight, in 1/1000 of em size (PDF units)*/
	int						GetCapHeight();
	//<<<+++OPENSOURCE_END
	/**Get font's underline position, in 1/1000 of em size (PDF units)*/
	int                     GetULPos();

	/**Get font's underline thickness, in 1/1000 of em size (PDF units)*/
	int                     GetULthickness();
   
	/**Get font's max advance width, in 1/1000 of em size (PDF units)*/
	int                     GetMaxAdvanceWidth();                     

	/** Embedded face or substitution faces. NULL if font is provided by external font provider.  */
	FXFT_Face				m_Face;
	/** The substitute font. for non-embedded font only. */
	CFX_SubstFont*			m_pSubstFont;

	FX_BOOL					IsEmbedded() { return m_bEmbedded; }
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	FX_BOOL					IsCached()	{ return m_bCached; }
	//<<<+++OPENSOURCE_END
	/* For MM font only: adjust width and weight paramaters for a particular glyph */
	void					AdjustMMParams(int glyph_index, int width, int weight);

	FX_LPBYTE				m_pFontDataAllocation;
	FX_LPBYTE               m_pFontData;
	FX_LPBYTE				m_pGsubData;
	FX_DWORD                m_dwSize;
	CFX_BinaryBuf           m_OtfFontData;
	void*                   m_hHandle;
	void*                   m_pPlatformFont; // GdipFont or Apple font
	void*                   m_pPlatformFontCollection;// GpFontCollection
	void*                   m_pDwFont; // DWrite font.
	FX_BOOL                 m_bDwLoaded;
	void                    ReleasePlatformResource();
	/*	delete face*/
	void					DeleteFace();
protected:
	/** Font encoding */
	FX_BOOL					m_bEmbedded;
	FX_BOOL					m_bVertical;
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	FX_BOOL                 m_bLogic;
	//<<<+++OPENSOURCE_END
	void*					m_pOwnedStream;
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	FX_BOOL					m_bCached;
	//<<<+++OPENSOURCE_END
};

/** @brief Whatever internal encoding in the font. */
#define ENCODING_INTERNAL		0
/** @brief Unicode encoding. */
#define ENCODING_UNICODE		1

/**
 * @brief Font encoding interface. It works with a font to translate character codes into glyph indices in that font.
 *	It also deals with Unicode mapping (if supported).
 */
class IFX_FontEncoding : public CFX_Object
{
public:
	virtual ~IFX_FontEncoding() {}

	/**
	 * Get the glyph index for a charcode. Return -1 for unknown. For embedded font only.
	 *
	 * @param[in] charcode		Input a charcode.
	 * @return The glyph index of the charcode.
	 */
	virtual FX_DWORD		GlyphFromCharCode(FX_DWORD charcode) = 0;
	/**
	 * Get a unicode string for a charcode. Return empty for unknown.
	 *
	 * @param[in] charcode		Input a charcode.
	 * @return The unicode string for the charcode.
	 */
	virtual CFX_WideString	UnicodeFromCharCode(FX_DWORD charcode) const = 0;
	/**
	 * Get a charcode from a Unicode. Return -1 for unknown.
	 *
	 * @param[in] Unicode		Input a unicode.
	 * @return The charcode for the unicode.
	 */
	virtual FX_DWORD		CharCodeFromUnicode(FX_WCHAR Unicode) const = 0;
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	/** Check whether the encoding is Unicode compatible. */
	virtual FX_BOOL			IsUnicodeCompatible() const = 0;

	virtual FX_DWORD		GlyphFromCharCodeEx(FX_DWORD charcode,int encoding = ENCODING_UNICODE)=0;
	//<<<+++OPENSOURCE_END
};

IFX_FontEncoding* FXGE_CreateUnicodeEncoding(CFX_Font* pFont);

/**
* @name Font encoding related operation
*/
/*@{*/

/** @brief This macro converts four-letter tags into an unsigned long. */
#define FXFM_ENC_TAG(a, b, c, d) (((FX_DWORD)(a) << 24) | ((FX_DWORD)(b) << 16) | ((FX_DWORD)(c) << 8) | (FX_DWORD)(d))

#define FXFM_ENCODING_NONE				FXFM_ENC_TAG(0, 0, 0, 0)							
#define FXFM_ENCODING_MS_SYMBOL			FXFM_ENC_TAG('s', 'y', 'm', 'b')		
#define FXFM_ENCODING_UNICODE			FXFM_ENC_TAG('u', 'n', 'i', 'c')
#define FXFM_ENCODING_MS_SJIS			FXFM_ENC_TAG('s', 'j', 'i', 's')
#define FXFM_ENCODING_MS_GB2312			FXFM_ENC_TAG('g', 'b', ' ', ' ')
#define FXFM_ENCODING_MS_BIG5			FXFM_ENC_TAG('b', 'i', 'g', '5')
#define FXFM_ENCODING_MS_WANSUNG		FXFM_ENC_TAG('w', 'a', 'n', 's')
#define FXFM_ENCODING_MS_JOHAB			FXFM_ENC_TAG('j', 'o', 'h', 'a')
#define FXFM_ENCODING_ADOBE_STANDARD	FXFM_ENC_TAG('A', 'D', 'O', 'B')
#define FXFM_ENCODING_ADOBE_EXPERT		FXFM_ENC_TAG('A', 'D', 'B', 'E')
#define FXFM_ENCODING_ADOBE_CUSTOM		FXFM_ENC_TAG('A', 'D', 'B', 'C')
#define FXFM_ENCODING_ADOBE_LATIN_1		FXFM_ENC_TAG('l', 'a', 't', '1')
#define FXFM_ENCODING_OLD_LATIN_2		FXFM_ENC_TAG('l', 'a', 't', '2')
#define FXFM_ENCODING_APPLE_ROMAN		FXFM_ENC_TAG('a', 'r', 'm', 'n')	

/** @brief The extension font encoding interface. */
class IFX_FontEncodingEx : public IFX_FontEncoding
{
public:
	/**
	* Get the glyph index from a name. Return -1 for unknown. For embedded font only.
	*
	* @param[in] pStrName		Input a character name.
	* @return The glyph index of the charcode.
	*/
	virtual FX_DWORD		GlyphIndexFromName(FX_LPCSTR pStrName) = 0;

	/**
	* Get the glyph name from a glyph index.
	*
	* @param[in] dwGlyphIndex		Input a glyph index.
	* @return The glyph name of the glyph index.
	*/
	virtual CFX_ByteString	NameFromGlyphIndex(FX_DWORD dwGlyphIndex) = 0;

	/**
	* Get the charcode from a glyph index. Return -1 for unknown. For embedded font only.
	*
	* @param[in] dwGlyphIndex		Input a glyph index.
	* @return The charcode of the glyph index.
	*/
	virtual FX_DWORD		CharCodeFromGlyphIndex(FX_DWORD dwGlyphIndex) = 0;
};

/**
* Create extension font encoding interface
*
* @param[in] pFont					Pointer to the font context.
* @param[in] nEncodingID			The encoding id to select the char map. Describes in FXFM_ENCODING_XXX.
* @return NULL for failure(such as, the nEncodingID can't be found).
*/
IFX_FontEncodingEx*	FX_CreateFontEncodingEx(CFX_Font* pFont, FX_DWORD nEncodingID = FXFM_ENCODING_NONE);

/*@}*/

/**
 * @name Substitute font flags.
 */
/*@{*/

/** @brief Use multi-master technology for substitution. */
#define FXFONT_SUBST_MM				0x01
/**
 * @brief Support glyph path data.
 * For external font provider only (since internal font provider always support glyph path).
 */
#define FXFONT_SUBST_GLYPHPATH		0x04
/**
 * @brief Support ClearType bitmap (3x width). 
 * For external font provider only (since internal font provider always support ClearType).
 */
#define FXFONT_SUBST_CLEARTYPE		0x08
/**
 * @brief Support transformed glyph.
 * For external font provider only (since internal font provider always support transform).
 */
#define FXFONT_SUBST_TRANSFORM		0x10
/** @brief Non-symbol font. */
#define FXFONT_SUBST_NONSYMBOL		0x20
/** @brief We have exact match. */
#define FXFONT_SUBST_EXACT			0x40
/** @brief If the font is substitutable. */
#define FXFONT_SUBST_STANDARD		0x80
//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
#define FXFONT_SUBST_PSEUDOSTANDARD	0x100
//<<<+++OPENSOURCE_END
/*@}*/

/** @brief Substitution font. */
class CFX_SubstFont : public CFX_Object
{
public:
	/** Default constructor. */
	CFX_SubstFont();

	/** Returned by external font provider. */
	FX_LPVOID				m_ExtHandle;
	/** Font family name. */
	CFX_ByteString			m_Family;
	/** Substituted Windows charset ID. */
	int						m_Charset;
	/** See definition of FXFONT_SUBST_xxxx constants. */
	FX_DWORD				m_SubstFlags;
	/** Weight parameter, non-zero for synthetic weight generation only */
	int						m_Weight;
	/** Italic angle, measured in degrees counterclockwise from the vertical.
	* Useful for synthetic italic generation only */
	int						m_ItalicAngle;
	/** Whether substitute the CJK font. */
	FX_BOOL					m_bSubstOfCJK;
	/** Weight parameter for CJK char, non-zero for synthetic weight generation only. */
	int						m_WeightCJK;
	/** Italic parameter for CJK char, non-zero for synthetic weight generation only. */
	FX_BOOL					m_bItlicCJK;
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	/** Face scale of substituted font relative to the original font. */
	FX_FLOAT				m_fScale;
	//<<<+++OPENSOURCE_END
};

//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
/**
 * @brief Glyph provider.
 *
 * For alternative platforms only:
 * Glyph provider: responsible for mapping font into one of more system font, 
 * getting glyph info, rendering glyph bitmap, and getting glyph path data.
 * NOTE: there is another IPDF_FontMapper interface in case the system can provide
 * Type1 or TrueType faces for substitution.
 */
class IFX_GlyphProvider : public CFX_Object
{
public:
	/**
	 * Map font. For most mobile system with only one font, this function can simply return NULL.
	 * 
	 * @param[in] name				Original name.
	 * @param[in] bTrueType			TrueType or Type1.
	 * @param[in] flags				font flags
	 * @param[in] font_weight		original font weight. 0 for not specified.
	 * @param[in] WindowPC			code page for charset (see Win32 GetACP()).
	 * @param[out] pSubstFont		It receives the substitute font data.
	 * @return The mapped font.
	 */
	virtual FX_LPVOID	MapFont(const CFX_ByteString& name, FX_BOOL bTrueType, FX_DWORD flags,
								int font_weight, int WindowPC, CFX_SubstFont* pSubstFont)
							{ return NULL; }

	/**
	 * Return the glyph bounding box in PDF font units (1000 units per em).
	 *
	 * @param[in] font_handle		Returned by IPDF_GlyphProvider::MapFont.
	 * @param[in] unicode			Unicode for the character.	
	 * @param[in] pFont				The font.
	 * @return The glyph bounding box.
	 */
	virtual FX_RECT		GetGlyphBBox(FX_LPVOID font_handle, FX_WCHAR unicode,
							CFX_Font* pFont) = 0;

	/** @brief glyph bitmap type enumeration. */
	typedef enum {
		Mono,			/**< A monochrome bitmap, using 1 bit per pixel. */
		ByteMask,		/**< An 8-bit bitmap, generally used to represent anti-aliased glyph images. */
		ClearType		/**< An 8-bit ClearType bitmap (3x width). */
	} BitmapType;

	/**
	 * Get glyph bitmap. Implementation of this interface is required.
	 *
	 * @param[in] font_handle		Returned by MapFont.
	 * @param[in] unicode			Unicode for the character.
	 * @param[in] pFont				The PDF font.
	 * @param[in] pMatrix			The character matrix. Only a,b,c,d used.
	 * 								If the substitute flag indicates glyph transformation supported, then this can be
	 * 								any kind of matrix. Otherwise, only a,d have value, and a == d.
	 * @param[in,out] type			Bitmap type requested.
	 *								On return, this is the type actually offered by the provider.
	 * @param[out] left				Offset from the char origin to left side of the bitmap.
	 *								Negative is to the left, positive is to the right.
	 * @param[out] top				offset from the char origin to top side of the bitmap.
	 *								Negative is downward, positive is upward.
	 * @param[out] pixel_width		Width (in pixels) of the result bitmap.
	 * @param[out] pixel_height		Height (in pixels) of the result bitmap.
	 * @param[out] buffer			Result buffer. Must be allocated using FX_Alloc.
	 *								The buffer will be freed by FPDFAPI.
	 * @param[out] stride			Number of bytes per line in the result bitmap.
	 * @param[in] dest_width		The intended width of the character in the document. 0 for not specified.
	 * @return Return TRUE for success, FALSE for failure (or empty glyph).
	 */
	virtual FX_BOOL		GetGlyphBitmap(FX_LPVOID font_handle, FX_WCHAR unicode, CFX_Font* pFont,
							const CFX_AffineMatrix* pMatrix, BitmapType& type,
							int& left, int& top, int& pixel_width, int& pixel_height, 
							FX_LPBYTE& buffer, int& stride, int dest_width) = 0;

	/**
	 * Get glyph path. Implementation of this interface is optional.
	 * The path data must be allocated using FX_NEW (it will be freed by FPDFAPI).
	 *
	 * @param[in] font_handle			Returned by MapFont.
	 * @param[in] unicode				Unicode for the character.
	 * @param[in] pFont					The font.
	 * @return The glyph path data. Return NULL for failure (or empty glyph).
	 */
	virtual class CFX_PathData*	GetGlyphPath(FX_LPVOID font_handle, FX_WCHAR unicode,
							CFX_Font* pFont)  { return NULL; }

	/** 
	 * Get glyph width in 1/1000 of em size (PDF units).
 	 * Implementation of this interface is optional.
	 * @param[in] glyph_index		    glyph index for the character.
	 * @param[in] pFont					The font.
	 * @return                          Glyph width
	 */	
	virtual int GetGlyphWidth(FX_DWORD glyph_index, CFX_Font* pFont)  { return 0; }
	/** 
	 * Get font ascent in 1/1000 of em size (PDF units).

 	 * Implementation of this interface is optional.
	 * @return                          Font ascent.
	 */
	virtual int GetAscent(const CFX_Font* pFont)  { return 0; }

	/** 
	 * Get font descent in 1/1000 of em size (PDF units).
 	 * Implementation of this interface is optional.
	 */	
	virtual int GetDescent(const CFX_Font* pFont)  { return 0; }
	/** 
	 * whether it is italic font.
 	 * Implementation of this interface is optional.
	 */		
	virtual FX_BOOL IsItalic(CFX_Font* pFont)  { return FALSE; }	
	/** 
	 * whether it is bold font.
 	 * Implementation of this interface is optional.
	 */		
	virtual FX_BOOL IsBold(CFX_Font* pFont)  { return FALSE; }			
};
//<<<+++OPENSOURCE_END
/** 
 * @name Macro definitions for font flags
*/
/**@{*/ 
/** @brief Glyphs have serifs, which are short strokes drawn at an angle on the top and bottom of glyph stems. */
#define FX_FONT_FLAG_SERIF              0x01
/** @brief All glyphs have the same width.*/
#define FX_FONT_FLAG_FIXEDPITCH			0x02
/** @brief  Glyphs have dominant vertical strokes that are slanted.*/
#define FX_FONT_FLAG_ITALIC				0x04
/** @brief  Bold font weight makes text darker than the surrounding text.*/
#define FX_FONT_FLAG_BOLD				0x08
/** @brief Font contains glyphs outside the Adobe standard Latin character set. 
 * This font has built-in Symbol encodings.
 */
#define FX_FONT_FLAG_SYMBOLIC_SYMBOL	0x10 
/** @brief Font contains glyphs outside the Adobe standard Latin character set. 
 * This font has built-in ZapfDingbats encodings.
 */
#define FX_FONT_FLAG_SYMBOLIC_DINGBATS	0x20
/** @brief A multiple master font that allows the generation of a wide variety of typeface styles from a single font. */
#define FX_FONT_FLAG_MULTIPLEMASTER		0x40

typedef struct {
	FX_LPCBYTE	m_pFontData;
	FX_DWORD	m_dwSize;
} FoxitFonts;

#ifdef _FXM_OPENSOURCE_
class CFX_FontMgr : public CFX_Object
#else
//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
class CFX_FontMgr : public CFX_LockObject
//<<<+++OPENSOURCE_END
#endif
{
public:
	CFX_FontMgr();
	~CFX_FontMgr();

	void			InitFTLibrary();

	FXFT_Face		GetCachedFace(const CFX_ByteString& face_name, 
							int weight, FX_BOOL bItalic, FX_LPBYTE& pFontData);
	FXFT_Face		AddCachedFace(const CFX_ByteString& face_name, 
							int weight, FX_BOOL bItalic, FX_LPBYTE pData, FX_DWORD size, int face_index);
	FXFT_Face		GetCachedTTCFace(int ttc_size, FX_DWORD checksum,
							int font_offset, FX_LPBYTE& pFontData);
	FXFT_Face		AddCachedTTCFace(int ttc_size, FX_DWORD checksum,
							FX_LPBYTE pData, FX_DWORD size, int font_offset);

	FXFT_Face		GetFileFace(FX_LPCSTR filename, int face_index);
	FXFT_Face		GetFixedFace(FX_LPCBYTE pData, FX_DWORD size, int face_index);

	void			ReleaseFace(FXFT_Face face);

	void			SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo);

	FXFT_Face		FindSubstFont(const CFX_ByteString& face_name, FX_BOOL bTrueType, FX_DWORD flags, 
						int weight, int italic_angle, int CharsetCP, CFX_SubstFont* pSubstFont);
    /*Must be called after CloseDocument.*/
	void			FreeCache();
//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	/**
	 * @brief Make use of external standard fonts for fxcore, can be called multiple times.
	 * 
     * @details In the standard 14 fonts can be classified as 4 kinds:
     * <ul>
     * <li>Serif fonts: Times-Roman, Time-Bold, Times-Italic, Times-BoldItalic</li>
     * <li>Sans-serif fonts: Helvetica, Helvetica-Bold, Helvetica-Oblique, Helvetica-BoldOblique</li>
     * <li>Fixed pitch(mono spaced) fonts: Courier, Courier-Bold, Courier-Oblique, Courier-BoldOblique</li>
     * <li>Symbolic fonts: Symbol, ZapfDingbats.</li>
     * </ul>
	 * 
	 *When our rendering engine could not find a suitable substitution font, will use two kinds of multiple master 
     *font to emulate the serif and sans-serif fonts.
	 *
	 * @param[in]   pFontData       Pointer to the font data.
	 * @param[in]   size            Number of bytes in the font data.
	 * @param[in]   flags           The font flags. See macro definitions <b>FX_FONT_FLAG_XXX</b>.
	 *
	 * @return None-zero means success, otherwise failure.
	 */
	FX_BOOL			UseExternalStandardFont(FX_LPCBYTE pFontData, FX_DWORD size, int flags);
	//<<<+++OPENSOURCE_END
	/* @brief Get fontdata from index.
	 * @param[out]   pFontData       Pointer to the font data.
	 * @param[out]   size            Number of bytes in the font data.
	 * @param[in]    index           index, from 0 to 15.
	 *
	 * @return None.
	 */
	FX_BOOL			GetStandardFont(FX_LPCBYTE& pFontData, FX_DWORD& size, int index);

	CFX_FontMapper*	m_pBuiltinMapper;	// the builtin generic mapper
	IFX_FontMapper*	m_pExtMapper;		// optional external mapper
	CFX_MapByteStringToPtr	m_FaceMap;			// Map face name to CTTFontDesc*
												// For TTC faces, the key is "<ttc_size>:<checksum>"
	FXFT_Library	m_FTLibrary;

	FoxitFonts m_ExternalFonts[16]; // Store the 16 external font data.

};

/**
 * @brief Font mapper interface.
 * Platform support may derive a font mapper from this class, and use CFX_GEModule::SetExtFontMapper() to 
 * set into FXGE font mapping chain. FXGE will first consult the external mapper when mapping a font.
 * Platform support should maintain the mapper object by itself (for new and delete).
 */
#ifdef _FXM_OPENSOURCE_
class IFX_FontMapper : public CFX_Object
#else
//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
class IFX_FontMapper : public CFX_LockObject
//<<<+++OPENSOURCE_END
#endif
{
public:
	/** The destructor. */
	virtual ~IFX_FontMapper() {}

	/**
	 * Find a substitute font. Return NULL if font not available, or not interested (in case of external font mapper).
	 *
	 * @param[in] pDoc				The PDF document.
	 * @param[in] face_name			Original name.
	 * @param[in] bTrueType			TrueType or Type1.
	 * @param[in] flags				PDF font flags (see PDF Reference section 5.7.1).
	 * @param[in] weight			original font weight. 0 for not specified.
	 * @param[in] CharsetCP			code page for charset (see Win32 GetACP()).
	 * @param[out] pSubstFont		It receives the substitute font data. 
	 * @return The font face.
	 */
	virtual FXFT_Face	FindSubstFont(const CFX_ByteString& face_name, FX_BOOL bTrueType, FX_DWORD flags,
							int weight, int italic_angle, int CharsetCP, CFX_SubstFont* pSubstFont) = 0;

	/** pointer to the font manager. Provided by after CFX_GEModule::SetExtFontMapper() called. */
	CFX_FontMgr*		m_pFontMgr;
};

/**
 * @brief A font enumerator interface the Application should implement.
 */
class IFX_FontEnumerator
{
public:
	/**
	 * Hit a font.
	 */
	virtual void		HitFont() = 0;

	/** 
	 * Font list is complete.
	 */
	virtual void		Finish() = 0;
};

/**
 * @brief Enum font information interface.
 * FXGE provides a generic enum  font information interface which uses a external font file to gather a font information.
 * available to the system. Implement this interface external. 
 */
class IFX_AdditionalFontEnum
{
public:
	virtual int  CountFiles() = 0;
	virtual IFX_FileStream* GetFontFile(int index) = 0;
};

/**
 * @brief Generic font mapper implemented by FXGE.
 */
class CFX_FontMapper : public IFX_FontMapper
{
public:
	CFX_FontMapper();
	virtual ~CFX_FontMapper();

	void				SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo);
	IFX_SystemFontInfo*	GetSystemFontInfo() { return m_pFontInfo; }

	void				AddInstalledFont(const CFX_ByteString& name, int charset);

	void				LoadInstalledFonts();
	CFX_ByteStringArray	m_InstalledTTFonts;	
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	// Set enum font information interface.
	FX_BOOL				SetAdditionalFontFile(IFX_AdditionalFontEnum* fontFile = NULL) { m_pAdditionalFontEnum = fontFile; return TRUE;}
	IFX_AdditionalFontEnum*	 GetAdditionalFontFile() const { return m_pAdditionalFontEnum; }
	//<<<+++OPENSOURCE_END
	void				SetFontEnumerator(IFX_FontEnumerator* pFontEnumerator) { m_pFontEnumerator = pFontEnumerator; }
	IFX_FontEnumerator*	GetFontEnumerator() const { return m_pFontEnumerator; }

	virtual FXFT_Face	FindSubstFont(const CFX_ByteString& face_name, FX_BOOL bTrueType, FX_DWORD flags, 
							int weight, int italic_angle, int CharsetCP, CFX_SubstFont* pSubstFont);
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	FX_BOOL				EnumAdditionalFontList();
	CFontFileFaceInfo*	MapAdditionalFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL& bExact);
	//<<<+++OPENSOURCE_END
private:
	CFX_ByteString		GetPSNameFromTT(void* hFont);
	CFX_ByteString		MatchInstalledFonts(const CFX_ByteString& norm_name);
	FXFT_Face			UseInternalSubst(CFX_SubstFont* pSubstFont, int iBaseFont, int italic_angle, int weight, int picthfamily);
	
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT	
	// Operation for additional font file.
	void				ScanAllAdditionalFiles();
	void				ScanAdditionalFile(IFX_FileStream* pFile);
	void				ReportAdditionalFace(IFX_FileStream* pFile, FX_DWORD filesize, FX_DWORD offset);
	//<<<+++OPENSOURCE_END
	FX_BOOL				m_bListLoaded;
	FXFT_Face			m_MMFaces[2];		// Foxit Sans MM, Foxit Serif MM
	CFX_ByteString		m_LastFamily;
	CFX_DWordArray		m_CharsetArray;
	CFX_ByteStringArray	m_FaceArray;
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT	
	IFX_AdditionalFontEnum* m_pAdditionalFontEnum;
	CFX_MapByteStringToPtr	m_AdditionalFontList;
	int					m_OldAdditionalNum;
	//<<<+++OPENSOURCE_END
	IFX_SystemFontInfo*	m_pFontInfo;
	FXFT_Face			m_FoxitFaces[14];	// Base14 fonts

	IFX_FontEnumerator*		m_pFontEnumerator;
};

/**
 * @brief System font information interface.
 * FXGE provides a generic font mapper which uses a system font info interface to gather a list of fonts
 * available to the system. Implement this interface for each environment and 
 */
class IFX_SystemFontInfo : public CFX_Object
{
public:
	static IFX_SystemFontInfo*	CreateDefault();

	// Release the interface
	virtual void		Release() = 0;

	// Enumerate font. Should call CFX_FontMapper::AddInstalledFont() for each font found
	// Return FALSE if font list not available
	virtual	FX_BOOL		EnumFontList(CFX_FontMapper* pMapper) = 0;

	// Map font. Return a font handle, or NULL if system doesn't support mapping
	virtual void*		MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR face, FX_BOOL& bExact) = 0;

	// Get a font.
	virtual void*		GetFont(FX_LPCSTR face) = 0;

	// Get font data.
	virtual FX_DWORD	GetFontData(void* hFont, FX_DWORD table, FX_LPBYTE buffer, FX_DWORD size) = 0;

	// Get face name. Return FALSE is not supported.
	virtual FX_BOOL		GetFaceName(void* hFont, CFX_ByteString& name) = 0;

	// Get font charset. Return FALSE is not supported.
	virtual FX_BOOL		GetFontCharset(void* hFont, int& charset) = 0;

	// Optional, platform font infomation can provide a specified face index in a ttc font.
	virtual int			GetFaceIndex(void* hFont) { return 0; }

	// Delete a font
	virtual void		DeleteFont(void* hFont) = 0;
    
    // Optional, for platform font support. 
    // Retain a font, the font handle will be takeover by CFX_Font and release when CFX_Font::ReleasePlatformResource
    // NOTE: Makesure you know what you do.
    // Return Non-zero means success, otherwise failure.
    virtual void*       RetainFont(void* hFont) { return NULL; }
};

// A generic folder based font mapper, currently used on Linux and Mac
class CFX_FolderFontInfo : public IFX_SystemFontInfo
{
public:
	CFX_FolderFontInfo();
	~CFX_FolderFontInfo();

	// Add one path to the mapper. All TT and OT fonts under this folder will be used.
	void				AddPath(FX_BSTR path);

	virtual void		Release();
	virtual	FX_BOOL		EnumFontList(CFX_FontMapper* pMapper);
	virtual void*		MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR face, FX_BOOL& bExact);
	virtual void*		GetFont(FX_LPCSTR face);
	virtual FX_DWORD	GetFontData(void* hFont, FX_DWORD table, FX_LPBYTE buffer, FX_DWORD size);
	virtual void		DeleteFont(void* hFont);
	virtual	FX_BOOL		GetFaceName(void* hFont, CFX_ByteString& name);
	virtual FX_BOOL		GetFontCharset(void* hFont, int& charset);

protected:
	CFX_MapByteStringToPtr	m_FontList;
	CFX_ByteStringArray	m_PathList;
	CFX_FontMapper*		m_pMapper;

	void				ScanPath(CFX_ByteString& path);
	void				ScanFile(CFX_ByteString& path);
	void				ReportFace(CFX_ByteString& path, FXSYS_FILE* pFile, FX_DWORD filesize, FX_DWORD offset);
};

class CFX_CountedFaceCache : public CFX_Object
{
public:
	CFX_FaceCache*	m_Obj;
	FX_DWORD		m_nCount;
};

typedef CFX_MapPtrTemplate<FXFT_Face, CFX_CountedFaceCache*> CFX_FTCacheMap;

#ifdef _FXM_OPENSOURCE_
class CFX_FontCache : public CFX_Object
#else
//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
class CFX_FontCache : public CFX_LockObject
//<<<+++OPENSOURCE_END
#endif
{
public:
	~CFX_FontCache();

	CFX_FaceCache*			GetCachedFace(CFX_Font* pFont);
	void					ReleaseCachedFace(CFX_Font* pFont);

	void					FreeCache(FX_BOOL bRelease = FALSE);
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
#ifdef FXFONT_GE_USECACHE_
	CFX_FontCache(IFX_Cache* pCache = NULL) { m_pCache = pCache; }
	void					Purge(FX_BOOL bForce);
private:
	IFX_Cache*				m_pCache;
#endif
	//<<<+++OPENSOURCE_END
		
private:
	CFX_FTCacheMap			m_FTFaceMap;		// caches used by FT faces (either embedded or substituted)
	CFX_FTCacheMap			m_ExtFaceMap;		// caches used by external faces (those using external glyph provider)
};

class CFX_AutoFontCache
{
public:
	CFX_AutoFontCache(CFX_FontCache* pFontCache, CFX_Font* pFont)
		: m_pFontCache(pFontCache)
		, m_pFont(pFont)
	{
	}
	~CFX_AutoFontCache()
	{
		m_pFontCache->ReleaseCachedFace(m_pFont);
	}
	CFX_FontCache* m_pFontCache;
	CFX_Font* m_pFont;
};
#define FX_FONTCACHE_DEFINE(pFontCache, pFont) CFX_AutoFontCache autoFontCache((pFontCache), (pFont))

//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
#ifdef FXFONT_GE_USECACHE_
class CFX_DIBitmapCache : public CFX_DIBitmap
{
public:
	CFX_DIBitmapCache() { m_dwRate = 1; m_bKeep = FALSE; m_pCache = NULL; m_pBufferCache = NULL;}
	FX_BOOL CreateAtCache(int width, int height, FXDIB_Format format, IFX_Cache* pCache = NULL);
	void TakeOver(CFX_DIBitmap* pSrcBitmap);
	~CFX_DIBitmapCache();
	FX_DWORD				m_dwRate;
	FX_BOOL					m_bKeep;
	FX_LPBYTE				m_pBufferCache;
private:
	IFX_Cache*				m_pCache;
};
#endif
//<<<+++OPENSOURCE_END

// Bitmap glyph
// 1bpp, 8bpp or 24bpp glyph bitmap
// 1bpp: for mono glyph;
// 8bpp: for normal grayscale bitmap
// 24bpp: for LCD grayscale bitmap
class CFX_GlyphBitmap : public CFX_Object
{
public:
	int						m_Top;				// top side bearing
	int						m_Left;				// left side bearing

#ifdef FXFONT_GE_USECACHE_
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	CFX_DIBitmapCache		m_Bitmap;
	//<<<+++OPENSOURCE_END
#else
	CFX_DIBitmap			m_Bitmap;
#endif
};

// Cache for a TT/T1 face, storing glyph bitmaps, and glyph paths
#ifdef _FXM_OPENSOURCE_
class CFX_FaceCache : public CFX_Object
#else
//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
class CFX_FaceCache : public CFX_LockObject
//<<<+++OPENSOURCE_END
#endif
{
public:
	~CFX_FaceCache();

	const CFX_GlyphBitmap*	LoadGlyphBitmap(CFX_Font* pFont, FX_DWORD glyph_index, FX_BOOL bFontStyle, const CFX_AffineMatrix* pMatrix, 
								int dest_width, int anti_alias, int& text_flags);

	const CFX_PathData*		LoadGlyphPath(CFX_Font* pFont, FX_DWORD glyph_index, int dest_width);
	
	

#ifdef FXFONT_GE_USECACHE_
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
    void					Purge(FX_BOOL bForce);
	CFX_FaceCache(FXFT_Face face, IFX_Cache* pCache = NULL);
	//<<<+++OPENSOURCE_END
#else
	CFX_FaceCache(FXFT_Face face);
#endif

private:
	FXFT_Face				m_Face;

	CFX_GlyphBitmap*		RenderGlyph(CFX_Font* pFont, FX_DWORD glyph_index, FX_BOOL bFontStyle, 
								const CFX_AffineMatrix* pMatrix, int dest_width, int anti_alias);

	CFX_GlyphBitmap*		RenderGlyph_Nativetext(CFX_Font* pFont, FX_DWORD glyph_index, 
								const CFX_AffineMatrix* pMatrix, int dest_width, int anti_alias);

    CFX_GlyphBitmap*        LookUpGlyphBitmap(CFX_Font* pFont, const CFX_AffineMatrix* pMatrix, CFX_ByteStringC& FaceGlyphsKey,
		                        FX_DWORD glyph_index, FX_BOOL bFontStyle, int dest_width, int anti_alias);




	CFX_MapByteStringToPtr	m_SizeMap;	// mapping font metrics to CPDF_SizeGlyphCache*
	CFX_MapPtrToPtr			m_PathMap;	// mapping glyph index to CFX_PathData*

	CFX_DIBitmap*           m_pBitmap;
	void*                   m_pPlatformGraphics; //GpGraphics or Apple device.
	void*                   m_pPlatformBitmap; //GpBitmap or Apple bitmap.
	void*                   m_hDC; //windows dc.
	void*                   m_hBitmap; // windows bitmap.
    void*                   m_hOldBitmap; // old bitmap;
	void*                   m_hGdiFont; // windows gdi font.
	void*                   m_hOldGdiFont; // windows gdi font.
	
#ifdef FXFONT_GE_USECACHE_
	//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	IFX_Cache*				m_pCache;
	//<<<+++OPENSOURCE_END
#endif

	// Platform dependant operations
	void				    InitPlatform();
	void				    DestroyPlatform();
};

typedef struct 
{
	const CFX_GlyphBitmap*	m_pGlyph;
	int					m_OriginX, m_OriginY;		// rounded to device pixel
	FX_FLOAT			m_fOriginX, m_fOriginY;		// original origin data
} FXTEXT_GLYPHPOS;

FX_RECT FXGE_GetGlyphsBBox(FXTEXT_GLYPHPOS* pGlyphAndPos, int nChars, int anti_alias, FX_FLOAT retinaScaleX = 1.0f, FX_FLOAT retinaScaleY = 1.0f);

FX_BOOL	OutputGlyph(void* dib, int x, int y, CFX_Font* pFont, double font_size,
											CFX_AffineMatrix* pMatrix, unsigned long glyph_index, unsigned long argb);
FX_BOOL	OutputText(void* dib, int x, int y, CFX_Font* pFont, double font_size,
				CFX_AffineMatrix* pText_matrix, unsigned short const* text, unsigned long argb);

class IFX_GSUBTable
{
public:
	virtual void	Release() = 0;

	virtual FX_BOOL GetVerticalGlyph(FX_DWORD glyphnum, FX_DWORD* vglyphnum) = 0;
};

IFX_GSUBTable* FXGE_CreateGSUBTable(CFX_Font* pFont);

//<<<+++OPENSOURCE_MUST_BEGIN
#endif
//<<<+++OPENSOURCE_MUST_END

